
# grid classes
# TODO: needs to be structured so that move_h, etc. are called from ObjBlock instances
#
#       needs capability for large objects which extend between cells

class Grid(object):
    def __init__(self, upper_right_coords = [0,0]):
       self.upper_right_coords = upper_right_coords

class ObjBlock(object):
    """Represents an object located on the grid"""
    # needs a LOT more...
    def __init__(self, x, y, x_len, y_len):
        self.x = x
        self.y = y
        self.x_len = x_len
        self.y_len = y_len
        
             
       
class SquareGrid(Grid):
    def __init__(self, x_blocks, y_blocks, block_size = [10,10], upper_right_coords = [0,0]):
        Grid.__init__(self)
        self.block_size = block_size
        self.x_blocks = x_blocks
        self.y_blocks = y_blocks
        self.objects = {}
        
        self.x_block_coord = [] # map of bloc number to block coords
        for block in range(self.x_blocks):
            self.x_block_coord.append(self.upper_right_coords[0] + (block * self.block_size[0]) ) 
        
        self.y_block_coord = [] # map of bloc number to block coords
        for block in range(self.y_blocks):
            self.y_block_coord.append(self.upper_right_coords[1] + (block * self.block_size[1]) )
         
    def move(self, obj_name, dx = 0, dy = 0):
        """
        Move object relative to current position
            where dy is blocks to move along vertical axis
            and dx is blocks to move along horizontal axis
            NOTE: current design evaluates horizontal moves
            first, so collision detection may not work
            properly if large numbers are used.
        """
        for move in range(abs(dx)):
            if self.is_legal_move(self.objects[obj_name].x + dx, self.objects[obj_name].y + dy):
                self.objects[obj_name].x += (dx / abs(dx))
        for move in range(abs(dy)):
            if self.is_legal_move(self.objects[obj_name].x + dx, self.objects[obj_name].y + dy):
                self.objects[obj_name].y += (dy / abs(dy))
        
    
    def is_legal_move(self,x,y):
        if not self.is_outside_bounds(x,y):
            if not self.block_is_occupied(x,y):
                return True
        return False
    
    def is_outside_bounds(self, x,y):

        if (x,y) < (self.x_blocks, self.y_blocks):
            if (x,y) > (0,0):
                return False
        return True  
    
    def set_loc(self,obj_name, x,y):
        """set arbitrary location"""
        new_coords = (x,y)
        if self.is_legal_move(x,y):
            self.objects[obj_name].x = x
            self.objects[obj_name].y = y
                                            
            
    def block_is_occupied(self, x,y):
        # needs some work, not very efficient.
        # does not allow for objects spanning multiple cells.
        for obj in self.objects:
            if (self.objects[obj].x, self.objects[obj].y) == (x,y):
                #print str(coords), "is occupied"
                return True
        return False
        
    def get_obj_coords(self, obj_name):
        """returns object's coordinates in actual x/y plane"""
        return self.x_block_coord[self.objects[obj_name].x], \
                self.y_block_coord[self.objects[obj_name].y]
                
    def get_obj_loc(self, obj_name):
        """returns object's location on grid"""
        return self.objects[obj_name].x, self.objects[obj_name].y
        
    def add_object(self, obj_name, start_x, start_y):
        # sprites? etc?
        self.objects[obj_name] = ObjBlock(start_x, start_y, \
                                          self.block_size[0],self.block_size[1])
        

